<template>
  <div class="mod-config">
    <el-row :gutter="20">
      <!-- 新增 -->
      <el-col :span="6">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <b>看板</b>
            <div style="float: right;">
              <el-button type="primary" icon="el-icon-edit" @click="signEditHandle" circle title="编辑"></el-button>
              <el-button type="primary" icon="el-icon-plus" @click="signAddHandle" circle title="新增"></el-button>
              <el-button type="primary" icon="el-icon-delete" @click="signDelHandle(data)" circle title="删除"></el-button>
            </div>
          </div>
          <div style="cursor: pointer;" v-for="(item,index) in signTree" :key="'sign'+index" @click="getSignData(item.id,item.name)">{{item.name}}</div>
          <!--          <el-tree class="filter-tree" :data="signTree" :props="defaultProps" default-expand-all ref="tree" @node-click="getSignData">-->
          <!--          </el-tree>-->
        </el-card>
      </el-col>
      <el-col :span="18">
        <el-card class="box-card">
          <!--          <div slot="header" class="clearfix">
            <b>新建</b>
          </div> -->
          <div class="text item" style="padding-right: 20px;">
            <el-form>
              <el-form-item label="名称" label-width="40px">
                <el-input size="medium" v-model="boardData.name"></el-input>
              </el-form-item>
            </el-form>
          </div>
          <div class="text item" style="padding-right: 20px;">
            <div style="height: 33px;margin-top: 10px;">
              <div style="float: left;">
                <el-button type="primary" class="button" @click="addRow('widget')">添加行</el-button>
                <el-button type="primary" class="button" @click="addRow('param')">添加参数行</el-button>
              </div>
              <div style="float: right;">
                <el-button type="primary" class="button" @click="previewSign()">预览</el-button>
                <el-button type="success" class="button" @click="saveSign">保存</el-button>
                <!-- <el-button type="danger" class="button">取消</el-button> -->
              </div>
              <div style="clear: both;"></div>
            </div>
            <div v-for="(rowItem,rowIndex) in rowList" :key="rowIndex">
              <el-row v-if="rowItem.type == 'param'" style="margin-bottom: 10px;">
                <el-col :span="24">
                  <div style="min-height: 100px;border:solid #e7e7e7 1px;border-top: solid red 2px;padding: 10px 15px;">
                    <div class="param-header">
                      <div style="float: left;">参数行</div>
                      <div style="float: right;">
                        <el-button type="success" class="button" style="margin-right: 10px;" @click="addParams('param','add',rowIndex,'',{})">添加参数</el-button>
                        <i class="el-icon-close" style="font-weight: 900;margin-left: 15px;" @click="removeItem(rowIndex)"></i>
                      </div>
                      <div style="clear: both;"></div>
                    </div>
                    <div style="width: 95%;min-height: 35px;margin: 10px auto;border: solid 1px #e7e7e7;padding: 3px;">
                      <el-button-group style="margin: 0 3px;margin-bottom: 5px;" v-for="(paramsItem,paramsIndex) in rowItem.params" :key="paramsIndex">
                        <el-button type="info" plain>{{paramsItem.name}}</el-button>
                        <el-button type="info" plain icon="el-icon-edit-outline" title="编辑" @click="addParams('param','update',rowIndex,'',paramsItem)"></el-button>
                        <el-button type="info" plain icon="el-icon-edit" title="设置默认值" @click="defaultSetting('param',rowIndex,paramsIndex,'',paramsItem)"></el-button>
                        <el-button type="info" plain icon="el-icon-delete" title="删除" @click="paramsDelHandle(rowIndex,paramsIndex)"></el-button>
                      </el-button-group>
                    </div>
                  </div>
                </el-col>
              </el-row>
              <el-row v-if="rowItem.type == 'widget'" style="margin-bottom: 10px;">
                <el-col :span="24">
                  <div style="min-height: 100px;border:solid #e7e7e7 1px;border-top: solid green 2px;padding: 10px 15px;">
                    <div class="row-header" style="margin-bottom: 5px;">
                      <div style="float: left;">行</div>
                      <div style="float: right;">
                        <el-button type="success" class="button" style="margin-right: 10px;" @click="addInsideItem('column',rowIndex)">添加列</el-button>
                        <el-button type="success" class="button" style="margin-right: 10px;" @click="addInsideItem('insideParams',rowIndex)">添加内部参数行</el-button>
                        <i class="el-icon-close" style="font-weight: 900;margin-left: 15px;" @click="removeItem(rowIndex)"></i>
                      </div>
                      <div style="clear: both;"></div>
                    </div>
                    <el-row :gutter="20">
                      <el-col v-for="(paramRowItem,paramRowIndex) in rowItem.paramRows" :key="paramRowIndex" :span="24">
                        <div style="min-height: 100px;border:solid #e7e7e7 1px;border-top: solid red 2px;padding: 10px 15px;">
                          <div>
                            <div style="float: left;">参数行</div>
                            <div style="float: right;">
                              <el-button type="success" class="button" style="margin-right: 10px;" @click="addParams('inside','add',rowIndex,paramRowIndex,{})">添加参数</el-button>
                              <i class="el-icon-close" style="font-weight: 900;margin-left: 15px;" @click="removeInsideItem(rowIndex,paramRowIndex,'insideParams')"></i>
                            </div>
                            <div style="clear: both;"></div>
                          </div>
                          <div style="width: 95%;min-height: 35px;margin: 10px auto;border: solid 1px #e7e7e7;padding: 3px;">
                            <el-button-group style="margin: 0 3px;margin-bottom: 5px;" v-for="(paramsInsideItem,paramsInsideIndex) in paramRowItem.params" :key="paramsInsideIndex">
                              <el-button type="info" plain>{{paramsInsideItem.name}}</el-button>
                              <el-button type="info" plain icon="el-icon-edit-outline" title="编辑" @click="addParams('inside','update',rowIndex,paramRowIndex,paramsInsideItem)"></el-button>
                              <el-button type="info" plain icon="el-icon-edit" title="设置默认值" @click="defaultSetting('insideParam',rowIndex,paramRowIndex,paramsInsideIndex,paramsInsideItem)"></el-button>
                              <el-button type="info" plain icon="el-icon-delete" title="删除" @click="insideParamsDelHandel(rowIndex,paramRowIndex,paramsInsideIndex)"></el-button>
                            </el-button-group>
                          </div>
                        </div>
                      </el-col>
                      <el-col v-for="(widgetItem,widgetIndex) in rowItem.widgets" :key="'widget'+widgetIndex" :span="widgetItem.width">
                        <div style="min-height: 100px;border:solid #e7e7e7 1px;border-top: solid royalblue 2px;padding: 10px 15px;">
                          <div style="margin-bottom: 15px;">
                            <div style="float: left;">{{widgetItem.name}}</div>
                            <div style="float: right;">
                              <i class="el-icon-close" style="font-weight: 900;margin-left: 15px;" @click="removeInsideItem(rowIndex,widgetIndex,'column')"></i>
                            </div>
                            <div style="clear: both;"></div>
                          </div>
                          <div style="font-weight: 700;">名称</div>
                          <div style="margin: 5px auto;">
                            <el-input v-model="widgetItem.name"></el-input>
                          </div>
                          <div style="font-weight: 700;">宽度(1~24)</div>
                          <div style="margin: 5px auto;">
                            <el-input v-model="widgetItem.width"></el-input>
                          </div>
                          <div style="font-weight: 700;">图表</div>
                          <div style="margin: 10px auto;">
                            <el-select style="width: 100%;" v-model="widgetItem.widgetId" @change="chartChangeHandle($event,rowIndex,widgetIndex)">
                              <el-option v-for="item1 in widgetList" :key="item1.id" :label="item1.label" :value="item1.id"></el-option>
                            </el-select>
                          </div>
                        </div>
                      </el-col>
                    </el-row>
                  </div>
                </el-col>
              </el-row>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
    <!-- 弹窗，编辑 -->
    <!-- <edit-dialog v-if="editVisible" ref="editDialog" :title="title"></edit-dialog> -->
    <!-- 弹窗，过滤 -->
    <!-- <filter-setting v-if="filterVisible" ref="filterDialog"></filter-setting> -->
    <!-- 弹窗，添加参数 -->
    <parameter v-if="parameterVisible" ref="parameterDialog" @refreshParams="getParamsData"></parameter>
    <!-- 弹窗,设置默认值 -->
    <default-setting v-if="defaultVisible" ref="defaultDialog" @refreshParams="getDefaultData"></default-setting>
  </div>
</template>

<script>
  import CodeMirror from '../components/CodeMirror' // 编辑器
  import draggable from 'vuedraggable' // 拖拽
  import ChartTable from '@/components/chart/table'
  import FilterSetting from '../components/filter'

  import {
    getBoardData,
    getBoardList
  } from '@/api/cboard/cboard'

  var echarts = require('echarts');

  import {
    deleteBoard,
    updateBoard,
    saveNewBoard,
    getWidgetOne,
    widgetList,
    widCategoryList,
    getDataSetOne,
    getAggregateData,
    DatasetList,
    sourList,
    saveNewWidget,
    updateWidget,
    delWidget,
    selectSql
  } from '@/api/cboard/cboard'
  import { list } from "../../../const/setting";
  import { chartDataProcess } from '../util/chartDataProcess.js'

  import { parseOption } from '../util/lineService.js'

  import parameter from './parameter'
  import DefaultSetting from './defaultset'

  export default {
    data() {
      return {
        signTree: [],
        defaultProps: {

        },
        AggregateStr: {
          reload: false,
          datasetId: '',
          datasourceId: '',
          query: '',
          cfg: {
            rows: [],
            columns: {
              columnName: '',
              filterType: '',
              values: '',
              id: ''
            },
            filters: [],
            values: {
              column: '',
              aggType: '',
            },
          },
        },
        rowList: [],
        widgetList: [],
        datasetList: [],
        parameterVisible: false,
        defaultVisible: false,
        boardData: {
          id: '',
          userId: '',
          categoryId: '',
          name: '',
          userName: '',
          loginName: '',
          createTime: '',
          updateTime: '',
          layout: {
            type: '',
            rows: []
          },
          categoryName: '',
          edit: false,
          delete: false,
          widgetId: '',
          boardId: ''
        }
      }
    },
    components: {
      parameter,
      DefaultSetting
    },
    created() {
      this.getWidgetList();
      this.getSignList();
    },
    methods: {
      // 新增看板
      signAddHandle() {
          this.rowList = [];
          this.boardData.name = '';
          this.boardId = '';
      },
      // 编辑看板
      signEditHandle(id) {

      },
      // 删除看板
      signDelHandle() {
          let boardId = this.boardId;
          let name = this.boardData.name;
          this.$confirm('是否确认删除名称为' + name, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(function () {
              return deleteBoard(boardId)
          }).then(data => {
              this.$message.success('删除成功')
              this.getWidgetList();
              this.getSignList();
              this.rowList = [];
          })
      },
      // 获取看板数据
      getSignData(id,name) {
        this.boardData.name = name;
        this.boardId = id
        this.signTree.forEach(item => {
          if (item.id == id) {
            this.rowList = item.layout.rows
          }
        })
        this.rowList = [...this.rowList]
      },
      // 请求看板列表
      getSignList() {
        getBoardList().then(response => {
          this.signTree = response.data;
        })
      },

      // 添加行或者参数行
      addRow(type) {
        let obj = {}
        if(type == 'param'){
          obj = {
            type: type,
            params: []
          }
        }else{
          obj = {
            type: type,
            widgets: [],
            paramRows: []
          }
        }
        this.rowList.push(obj)
      },
      // 参数行添加参数
      addParams(about,type,index,insideIndex,data) {
        let widgetIdList = []
        this.rowList.forEach(item => {
          if(item.type == 'widget'){
            for (let i = 0; i < item['widgets'].length; i++) {
              widgetIdList.push(item['widgets'][i].widgetId)
            }
          }
        })
        this.parameterVisible = true
        this.$nextTick(() => {
          this.$refs.parameterDialog.init(about,type,index,insideIndex,data,widgetIdList)
        })
      },
      // 获取参数
      getParamsData(row){
        if(row.about == 'param'){
          if(row.type == 'add'){
            this.rowList[row.index].params.push(row.rowData)
          }else if(row.type == 'update'){
            this.rowList[row.index].params.forEach((item,index) => {
              if(row.rowData.timestamp == item.timestamp){
                this.rowList[row.index].params[index] = row.rowData
              }
            })
          }
        }else if(row.about == 'inside'){
          if(row.type == 'add'){
            this.rowList[row.index]['paramRows'][row.insideIndex].params.push(row.rowData)
          }else if(row.type == 'update'){
            this.rowList[row.index]['paramRows'][row.insideIndex].params.forEach((item,index) => {
              if(row.rowData.timestamp == item.timestamp){
                this.rowList[row.index]['paramRows'][row.insideIndex].params[index] = row.rowData
              }
            })
          }
        }
        this.rowList = [...this.rowList]
      },
      // 删除参数行参数
      paramsDelHandle(rowIndex,paramsIndex){
        this.rowList[rowIndex].params.splice(paramsIndex,1)
      },
      // 设置默认值
      defaultSetting(type,rowIndex,paramsIndex,insideParamsIndex,rowData){
        this.defaultVisible = true
        this.$nextTick(() => {
          this.$refs.defaultDialog.init(type,rowIndex,paramsIndex,insideParamsIndex,rowData)
        })
      },
      // 获取默认值
      getDefaultData(row){
          console.log(row)
        if(row.type == 'param'){
          this.rowList[row.rowIndex].params[row.paramsIndex] = row.paramsData
        }else if(row.type == 'insideParam'){
          this.rowList[row.rowIndex]['paramRows'][row.paramsIndex]['params'][row.insideParamsIndex] = row.paramsData
        }
        this.rowList = [...this.rowList]
      },
      // 删除行或者参数行
      removeItem(index) {
        this.rowList.splice(index, 1)
      },
      // 添加列或者内部参数行
      addInsideItem(type, index) {
        let obj = {}
        console.log(type)
        if (type == 'column') {
          obj = {
            type: type,
            name: '图表名称',
            width: 12,
          }
          obj.chartData = this.widgetList[0]['data']
          obj.chart = this.widgetList[0].id
          obj.datasetId = this.widgetList[0]['data']['datasetId']
          this.rowList[index]['widgets'].push(obj)
        } else if (type == 'insideParams') {
          obj = {
            type: type,
            params: []
          }
          this.rowList[index]['paramRows'].push(obj)
        }
      },
      // 内部参数行添加参数
      addInsideParams(index, idx) {
        let obj = {
          name: '参数'
        }
        this.rowList[index]['paramRows'][idx]['params'].push(obj)
      },
      // 删除列或者内部参数行
      removeInsideItem(index, idx, type) {
          if(type == 'insideParams') {
              this.rowList[index]['paramRows'].splice(idx, 1)
          }else if(type == 'column'){
              this.rowList[index]['widgets'].splice(idx, 1)
          }

      },
      // 删除内部参数行参数
      insideParamsDelHandel(rowIndex,insideIndex,insideParamsIndex){
        this.rowList[rowIndex]['paramRows'][insideIndex]['params'].splice(insideParamsIndex,1)
      },
      // 获取图表列表
      getWidgetList() {
        widgetList({}).then(response => {
          this.widgetList = response.data
          this.widgetList.forEach((item, index) => {
            item.label = item.name
            // getDataSetOne(item['data']['datasetId']).then(result => {
            //   item.label = item.name + '(' + result.data.name + ')'
            // })
          })
        })
      },
      chartChangeHandle(val, index, idx) {
        this.widgetList.forEach(item => {
          if (item.id == val) {
            this.rowList[index]['widgets'][idx].name = item.name
            this.rowList[index]['widgets'][idx].chartData = item.data
            this.rowList[index]['widgets'][idx].datasetId = item.data.datasetId
          }
        })
      },
      // 保存
      saveSign() {
        this.boardData.layout.rows =[];
        console.log(this.rowList)
        this.rowList.forEach((items, indexs) => {
            if(items.type == 'widget'){
              let obj = {
                  type: 'widget',
                  widgets: [],
                  paramRows: []
              }
              items.widgets.forEach((item, index) => {
                let widgetId = this.rowList[indexs].widgets[index].widgetId;
                let width = this.rowList[indexs].widgets[index].width;
                let name = this.rowList[indexs].widgets[index].name;
                let datasetId = this.rowList[indexs].widgets[index].datasetId;
                let tb = {
                    name: name,
                    width: width,
                    widgetId: widgetId,
                    datasetId: datasetId
                }
                obj.widgets.push(tb)
                this.boardData.id = this.boardId;
              })
              items.paramRows.forEach((item, index) => {
                let tb = {
                    params: item.params
                }
                obj.paramRows.push(tb)
                this.boardData.id = this.boardId;
              })
              this.boardData.layout.rows.push(obj);
            }else if(items.type == 'param'){
              let obj = {
                type: 'param',
                params: []
              }
              items.params.forEach((item,index) => {
                let col = this.rowList[indexs].params[index].col;
                let name = this.rowList[indexs].params[index].name;
                let paramType = this.rowList[indexs].params[index].paramType;
                let selects = this.rowList[indexs].params[index].selects;
                let type = this.rowList[indexs].params[index].type;
                let values = this.rowList[indexs].params[index].values;
                let tb = {
                  col: col,
                  name: name,
                  paramType: paramType,
                  selects: selects,
                  type: type,
                  values: values
                }
                obj.params.push(tb)
              })
              this.boardData.layout.rows.push(obj);
            }


        })
          console.log(this.boardData)
        let boardJson = JSON.stringify(this.boardData);

        if(this.boardId){
            updateBoard({
                mapStr: boardJson
            }).then(response => {
                this.$notify({
                    title: '成功',
                    message: '修改成功',
                    type: 'success',
                    duration: 2000
                })
            })
        }else{
            saveNewBoard({
                mapStr: boardJson
            }).then(response => {
                this.boardId = response.data.id;
                this.$notify({
                    title: '成功',
                    message: '保存成功',
                    type: 'success',
                    duration: 2000
                })
            })
        }
      },
      // 预览
      previewSign() {
        this.$confirm('预览之前需要保存，确定保存？','提示',
        {confirmButtonText:'确定',cancelButtonText:'取消',type:'warning'}).then(() => {
          this.saveSign()
          setTimeout(() => {
            this.$router.push({ path: '/cboard/demo/index',query: {id: this.boardId} })
          },1500)
        })
      },
      getDataSeries(chartConfig) {
        let that = this
        let result = [];
        _.each(chartConfig.values, function(v) {
          _.each(v.cols, function(c) {
            let series = that.configToDataSeries(c);
            _.each(series, function(s) {
              if (!_.find(result, function(e) {
                  return JSON.stringify(e) == JSON.stringify(s);
                })) {
                result.push(s);
              }
            });
          });
        });
        return result;
      },
      configToDataSeries(config) {
        switch (config.type) {
          case 'exp':
            return this.getExpSeries(config.exp);
            break;
          default:
            return [{
              name: config.col,
              aggregate: config.aggregate_type
            }];
            break;
        }
      },

      getExpSeries(exp) {
        return this.parserExp(exp).aggs;
      },
      parserExp(rawExp) {
        let evalExp = rawExp;
        let _temp = [];
        let aggs = [];
        evalExp = evalExp.trim().replace(/[\n|\r|\r\n]/g, '');

        _.each(evalExp.match(/".*?"/g), function(qutaText) {
          evalExp = evalExp.replace(qutaText, '_#' + _temp.length);
          _temp.push(qutaText);
        });

        let names = []; // expression text in aggreagtion function, could be a columnName or script
        _.each(evalExp.match(/(sum|avg|count|max|min|distinct)\("?.*?"?\)/g), function(aggUnit) {
          let aggregate = aggUnit.substring(0, aggUnit.indexOf('('));
          let name = aggUnit.substring(aggUnit.indexOf('(') + 1, aggUnit.indexOf(')'));
          if (name.match("_#")) {
            name = _temp[name.replace("_#", "")].replace(/\"/g, "");
          }
          evalExp = evalExp.replace(aggUnit, "groupData[_names[" + names.length + "]]['" + aggregate + "'][key]");
          names.push(name);
          aggs.push({
            name: name,
            aggregate: aggregate
          });
        });
        return {
          evalExp: evalExp,
          aggs: aggs,
          names: names
        };
      },
      getDimensionConfig(array) {
        let result = [];
        if (array) {
          _.each(array, function(e) {
            if (_.isUndefined(e.group)) {
              result.push({
                columnName: e.col,
                filterType: e.type,
                values: e.values,
                id: e.id
              });
            } else {
              _.each(e.filters, function(f) {
                result.push({
                  columnName: f.col,
                  filterType: f.type,
                  values: f.values
                });
              });
            }
          });
        }
        return result;
      },
    }
  }
</script>

<style lang="scss" scoped>
  .mod-config {
    padding: 10px 15px;
  }

  /deep/ .el-card {
    background-color: #fff;
  }

  /deep/ .el-card__body {
    padding: 0;
    padding-bottom: 20px;
  }

  .box-card .item {
    padding-left: 20px;
    padding-bottom: 10px;
    padding-top: 10px;
    border-bottom: solid 1px #e7e7e7;
  }

  .search {
    padding: 20px 20px 0 20px;
  }

  .filter-tree {
    margin-top: 20px;
  }

  /deep/ .el-tree {
    background-color: #fff;
  }

  .field-ul {
    padding-left: 24px;

    li {
      padding-left: 10px;
    }
  }

  .sign-list {
    cursor: pointer;
    padding-left: 15px;
    line-height: 35px;
  }

  .sign-list:hover {
    background-color: #e7e7e7;
  }
</style>
